import { Context, Schema, h, User } from 'koishi'
import {} from 'koishi-plugin-adapter-onebot';

export const name = 'lucky-atgroup'
export const using = ['database']

declare module 'koishi' {
  interface Tables {
    user_groups: UserGroup
    user_group_members: UserGroupMember
  }
}

interface UserGroup {
  id: number
  name: string
}

interface UserGroupMember {
  groupId: number
  userId: string
}

export interface Config {
  userWhitelist: string[],
  verboseConsoleOutput: boolean
}

export const Config: Schema<Config> = Schema.object({
  userWhitelist: Schema.array(String).description(""),
  verboseConsoleOutput: Schema.boolean().default(false).description('是否在控制台输出调试信息'),
})

export function apply(ctx: Context, config: Config) {
  // 定义数据库模型
  ctx.model.extend('user_groups', {
    id: 'unsigned',
    name: 'string',
  }, {
    autoInc: true,
    primary: 'id',
  })

  ctx.model.extend('user_group_members', {
    groupId: 'unsigned',
    userId: 'string',
  }, {
    primary: ['groupId', 'userId'],
  })

  const logger = ctx.logger('lucky-atgroup')

  async function isUserGroupAdmin(onebot: any, groupId: string, userId: string): Promise<boolean> {
    try {
      const res = await onebot._request('get_group_member_info', {
        group_id: groupId,
        user_id: userId,
        no_cache: false,
      });
  
      if (res.status === 'ok' && res.retcode === 0 && res.data) {
        const role = res.data.role;
        return role === 'admin' || role === 'owner';
      }
    } catch (err) {
      // 可以选择日志记录错误
    }
    return false;
  }

  // 创建用户组
  ctx.command('create <name:string>', '创建一个新的用户组')
    .alias("创建用户组")
    .action(async ({ session }, name) => {

      const isAdmin = await isUserGroupAdmin(session.onebot, session.guildId, session.userId);
      if ( !isAdmin && !config.userWhitelist.includes(session.userId) ) {
        await session.send("at权限不足：你不是管理员，也不在白名单中。");
        return;
      }

      const exist = await ctx.database.get('user_groups', { name })
      if (exist.length > 0) return `用户组 "${name}" 已存在。`

      await ctx.database.create('user_groups', { name })
      return `用户组 "${name}" 创建成功！`
    })

  // 添加成员
  ctx.command('add <name:string>', '添加成员到用户组')
    .alias("添加用户组")
    .action(async ({ session }, name) => {

      const isAdmin = await isUserGroupAdmin(session.onebot, session.guildId, session.userId);
      if ( !isAdmin && !config.userWhitelist.includes(session.userId) ) {
        await session.send("at权限不足：你不是管理员，也不在白名单中。");
        return;
      }

      // 查找目标用户组
      const group = await ctx.database.get('user_groups', { name })
      if (!group.length) return `用户组 "${name}" 不存在。`

      // 从消息中提取所有 @ 的用户元素
      const atUsers = session.elements
        .filter(e => e.type === 'at' && e.attrs.id)
        .map(e => e.attrs.id)

      if (!atUsers.length) return '请至少 @ 一个用户。'

      const groupId = group[0].id
      const members = atUsers.map(userId => ({ groupId, userId }))

      await ctx.database.upsert('user_group_members', members, ['groupId', 'userId'])

      return `已添加 ${atUsers.length} 位成员到 "${name}" 用户组。`
    })


  // 移除成员
  ctx.command('remove <name:string>', '从用户组移除成员')
    .alias("移除用户组")
    .action(async ({ session }, name) => {

      const isAdmin = await isUserGroupAdmin(session.onebot, session.guildId, session.userId);
      if ( !isAdmin && !config.userWhitelist.includes(session.userId) ) {
        await session.send("at权限不足：你不是管理员，也不在白名单中。");
        return;
      }
      
      const group = await ctx.database.get('user_groups', { name })
      if (!group.length) return `用户组 "${name}" 不存在。`

      // 提取消息中的所有 at 元素
      const atUsers = session.elements
        .filter(e => e.type === 'at' && e.attrs.id)
        .map(e => e.attrs.id)

      if (!atUsers.length) return '请至少 @ 一个用户。'

      const groupId = group[0].id

      await Promise.all(
        atUsers.map(userId =>
          ctx.database.remove('user_group_members', { groupId, userId })
        )
      )

      return `已从 "${name}" 用户组中移除 ${atUsers.length} 位成员。`
    })


  ctx.command('at <name:string>', '批量艾特用户组内所有成员')
    .alias("艾特用户组")
    .action(async ({ session }, name) => {

      const isAdmin = await isUserGroupAdmin(session.onebot, session.guildId, session.userId);
      if ( !isAdmin && !config.userWhitelist.includes(session.userId) ) {
        await session.send("at权限不足：你不是管理员，也不在白名单中。");
        return;
      }

      // 查询用户组是否存在
      const group = await ctx.database.get('user_groups', { name })
      if (!group.length) return `用户组 "${name}" 不存在。`

      // 查找用户组成员
      const members = await ctx.database.get('user_group_members', { groupId: group[0].id })
      if (!members.length) return `用户组 "${name}" 目前没有成员。`

      // // 生成 @ 成员字符串
      // const mentions = members.map(m => h.at(m.userId)).join(' ')
      // // 发送消息 @ 所有人
      // return session.send(`@${name}: \n\t${mentions}`)

      const mentions = members.map(m => h.at(m.userId))
      const msg = [h.text(`@${name}:\n`), ...mentions]
      return session.send(msg)
    })

    ctx.command('list-groups', '列出所有用户组名称')
      .alias('用户组列表')
      .action(async () => {
        const groups = await ctx.database.get('user_groups', {})
        if (!groups.length) return '目前没有任何用户组。'
        return '用户组列表：\n' + groups.map(g => `- ${g.name}`).join('\n')
      })
    
    ctx.command('show-group <name:string>', '查看指定用户组的成员')
      .alias('查看用户组')
      .action(async ({ session }, name) => {
        const group = await ctx.database.get('user_groups', { name })
        if (!group.length) return `用户组 "${name}" 不存在。`
    
        const members = await ctx.database.get('user_group_members', { groupId: group[0].id })
        if (!members.length) return `用户组 "${name}" 中暂无成员。`
    
        let lines = [`用户组 "${name}" 的成员列表：`]
    
        for (const m of members) {
          const user = await ctx.database.get('user', { id: Number(m.userId) })
          // const nickname = user[0]?.name || '(无用户名)'
          const userObj = await session.bot.getUser(m.userId, session.guildId);
          const username = userObj.name;
          // const usernick = userObj.nickname;
          lines.push(`- ${m.userId}(${username})`)
        }
    
        return lines.join('\n')
      })
    

  
    ctx.command('at_help', '显示关于用户组管理指令的帮助信息')
      .alias('用户组帮助')
      .action(async ({ session }) => {
        return `
          用户组管理指令说明：
          
          1. create <name> （创建用户组）
            创建一个新的用户组，名称唯一。
            示例：create friends
          
          2. add <name> （添加成员）
            向指定用户组添加成员，需要在消息中 @ 相关用户。
            示例：add friends @user1 @user2
          
          3. remove <name> （移除成员）
            从指定用户组移除成员，需要在消息中 @ 相关用户。
            示例：remove friends @user1
          
          4. at <name> （艾特用户组）
            批量艾特用户组内所有成员。
            示例：at friends
          
          5. list-groups （用户组列表）
            查看当前所有的用户组名称。
            示例：list-groups

          6. show-group <name> （查看用户组）
            查看指定用户组内所有成员（显示 ID 和昵称，不进行艾特）。
            示例：show-group friends

          也可以使用中文别名，如“创建用户组”、“用户组列表”等。
          `
      })


  if (config.verboseConsoleOutput) {
    logger.info('插件 lucky-atgroup 已启用，调试模式开启。')
  }
}
